home *** CD-ROM | disk | FTP | other *** search
/ PC/CD Gamer UK 120 / CD Gamer Issue 120 (March 2003) (Disc 2).ISO / mods / Q2_Codered / codeRED1_0.exe / Data1.cab / mdfour.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-08-13  |  5.3 KB  |  244 lines

  1. /*
  2.     $RCSfile: mdfour.c,v $
  3.  
  4.     Copyright (C) 1997-1998  Andrew Tridgell
  5.     Copyright (C) 2000       Jeff Teunissen <d2deek@pmail.net>
  6.  
  7.     This program is free software; you can redistribute it and/or
  8.     modify it under the terms of the GNU General Public License
  9.     as published by the Free Software Foundation; either version 2
  10.     of the License, or (at your option) any later version.
  11.  
  12.     This program is distributed in the hope that it will be useful,
  13.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  15.  
  16.     See the GNU General Public License for more details.
  17.  
  18.     You should have received a copy of the GNU General Public License
  19.     along with this program; if not, write to:
  20.     
  21.         Free Software Foundation, Inc.
  22.         59 Temple Place - Suite 330
  23.         Boston, MA  02111-1307, USA
  24.  
  25. */
  26. #include <string.h>
  27.  
  28. /* NOTE: This code makes no attempt to be fast!
  29.  
  30.    It assumes that a int is at least 32 bits long
  31. */
  32.  
  33. struct mdfour {
  34.     unsigned A, B, C, D;
  35.     unsigned totalN;
  36. };
  37.  
  38. static struct mdfour *m;
  39.  
  40. #define F(X,Y,Z) (((X)&(Y)) | ((~(X))&(Z)))
  41. #define G(X,Y,Z) (((X)&(Y)) | ((X)&(Z)) | ((Y)&(Z)))
  42. #define H(X,Y,Z) ((X)^(Y)^(Z))
  43. #define lshift(x,s) (((x)<<(s)) | ((x)>>(32-(s))))
  44.  
  45. #define ROUND1(a,b,c,d,k,s) a = lshift(a + F(b,c,d) + X[k], s)
  46. #define ROUND2(a,b,c,d,k,s) a = lshift(a + G(b,c,d) + X[k] + 0x5A827999,s)
  47. #define ROUND3(a,b,c,d,k,s) a = lshift(a + H(b,c,d) + X[k] + 0x6ED9EBA1,s)
  48.  
  49. /* this applies md4 to 64 byte chunks */
  50. static void mdfour64 (unsigned *M)
  51. {
  52.     int         j;
  53.     unsigned    AA, BB, CC, DD;
  54.     unsigned    X[16];
  55.     unsigned    A, B, C, D;
  56.  
  57.     for (j = 0; j < 16; j++)
  58.         X[j] = M[j];
  59.  
  60.     A = m->A;
  61.     B = m->B;
  62.     C = m->C;
  63.     D = m->D;
  64.     AA = A;
  65.     BB = B;
  66.     CC = C;
  67.     DD = D;
  68.  
  69.     ROUND1 (A, B, C, D, 0, 3);
  70.     ROUND1 (D, A, B, C, 1, 7);
  71.     ROUND1 (C, D, A, B, 2, 11);
  72.     ROUND1 (B, C, D, A, 3, 19);
  73.     ROUND1 (A, B, C, D, 4, 3);
  74.     ROUND1 (D, A, B, C, 5, 7);
  75.     ROUND1 (C, D, A, B, 6, 11);
  76.     ROUND1 (B, C, D, A, 7, 19);
  77.     ROUND1 (A, B, C, D, 8, 3);
  78.     ROUND1 (D, A, B, C, 9, 7);
  79.     ROUND1 (C, D, A, B, 10, 11);
  80.     ROUND1 (B, C, D, A, 11, 19);
  81.     ROUND1 (A, B, C, D, 12, 3);
  82.     ROUND1 (D, A, B, C, 13, 7);
  83.     ROUND1 (C, D, A, B, 14, 11);
  84.     ROUND1 (B, C, D, A, 15, 19);
  85.  
  86.     ROUND2 (A, B, C, D, 0, 3);
  87.     ROUND2 (D, A, B, C, 4, 5);
  88.     ROUND2 (C, D, A, B, 8, 9);
  89.     ROUND2 (B, C, D, A, 12, 13);
  90.     ROUND2 (A, B, C, D, 1, 3);
  91.     ROUND2 (D, A, B, C, 5, 5);
  92.     ROUND2 (C, D, A, B, 9, 9);
  93.     ROUND2 (B, C, D, A, 13, 13);
  94.     ROUND2 (A, B, C, D, 2, 3);
  95.     ROUND2 (D, A, B, C, 6, 5);
  96.     ROUND2 (C, D, A, B, 10, 9);
  97.     ROUND2 (B, C, D, A, 14, 13);
  98.     ROUND2 (A, B, C, D, 3, 3);
  99.     ROUND2 (D, A, B, C, 7, 5);
  100.     ROUND2 (C, D, A, B, 11, 9);
  101.     ROUND2 (B, C, D, A, 15, 13);
  102.  
  103.     ROUND3 (A, B, C, D, 0, 3);
  104.     ROUND3 (D, A, B, C, 8, 9);
  105.     ROUND3 (C, D, A, B, 4, 11);
  106.     ROUND3 (B, C, D, A, 12, 15);
  107.     ROUND3 (A, B, C, D, 2, 3);
  108.     ROUND3 (D, A, B, C, 10, 9);
  109.     ROUND3 (C, D, A, B, 6, 11);
  110.     ROUND3 (B, C, D, A, 14, 15);
  111.     ROUND3 (A, B, C, D, 1, 3);
  112.     ROUND3 (D, A, B, C, 9, 9);
  113.     ROUND3 (C, D, A, B, 5, 11);
  114.     ROUND3 (B, C, D, A, 13, 15);
  115.     ROUND3 (A, B, C, D, 3, 3);
  116.     ROUND3 (D, A, B, C, 11, 9);
  117.     ROUND3 (C, D, A, B, 7, 11);
  118.     ROUND3 (B, C, D, A, 15, 15);
  119.  
  120.     A += AA;
  121.     B += BB;
  122.     C += CC;
  123.     D += DD;
  124.  
  125.     for (j = 0; j < 16; j++)
  126.         X[j] = 0;
  127.  
  128.     m->A = A;
  129.     m->B = B;
  130.     m->C = C;
  131.     m->D = D;
  132. }
  133.  
  134. static void copy64 (unsigned *M, unsigned char *in)
  135. {
  136.     int         i;
  137.  
  138.     for (i = 0; i < 16; i++)
  139.         M[i] = (in[i * 4 + 3] << 24) | (in[i * 4 + 2] << 16) |
  140.             (in[i * 4 + 1] << 8) | (in[i * 4 + 0] << 0);
  141. }
  142.  
  143. static void copy4 (unsigned char *out, unsigned x)
  144. {
  145.     out[0] = (unsigned char)(x & 0xFF);
  146.     out[1] = (unsigned char)((x >> 8) & 0xFF);
  147.     out[2] = (unsigned char)((x >> 16) & 0xFF);
  148.     out[3] = (unsigned char)((x >> 24) & 0xFF);
  149. }
  150.  
  151. void mdfour_begin (struct mdfour *md)
  152. {
  153.     md->A = 0x67452301;
  154.     md->B = 0xefcdab89;
  155.     md->C = 0x98badcfe;
  156.     md->D = 0x10325476;
  157.     md->totalN = 0;
  158. }
  159.  
  160. static void mdfour_tail (unsigned char *in, int n)
  161. {
  162.     unsigned char buf[128];
  163.     unsigned M[16];
  164.     unsigned b;
  165.  
  166.     m->totalN += n;
  167.  
  168.     b = m->totalN * 8;
  169.  
  170.     memset (buf, 0, 128);
  171.     if (n)
  172.         memcpy (buf, in, n);
  173.     buf[n] = 0x80;
  174.  
  175.     if (n <= 55) {
  176.         copy4 (buf + 56, b);
  177.         copy64 (M, buf);
  178.         mdfour64 (M);
  179.     } else {
  180.         copy4 (buf + 120, b);
  181.         copy64 (M, buf);
  182.         mdfour64 (M);
  183.         copy64 (M, buf + 64);
  184.         mdfour64 (M);
  185.     }
  186. }
  187.  
  188. void mdfour_update (struct mdfour *md, unsigned char *in, int n)
  189. {
  190.     unsigned M[16];
  191.  
  192.     if (n == 0)
  193.         mdfour_tail (in, n);
  194.  
  195.     m = md;
  196.  
  197.     while (n >= 64) {
  198.         copy64 (M, in);
  199.         mdfour64 (M);
  200.         in += 64;
  201.         n -= 64;
  202.         m->totalN += 64;
  203.     }
  204.  
  205.     mdfour_tail (in, n);
  206. }
  207.  
  208.  
  209. void mdfour_result (struct mdfour *md, unsigned char *out)
  210. {
  211.     m = md;
  212.  
  213.     copy4 (out, m->A);
  214.     copy4 (out + 4, m->B);
  215.     copy4 (out + 8, m->C);
  216.     copy4 (out + 12, m->D);
  217. }
  218.  
  219. void mdfour (unsigned char *out, unsigned char *in, int n)
  220. {
  221.     struct mdfour md;
  222.  
  223.     mdfour_begin (&md);
  224.     mdfour_update (&md, in, n);
  225.     mdfour_result (&md, out);
  226. }
  227.  
  228. unsigned Com_BlockChecksum (void *buffer, int length)
  229. {
  230.     unsigned char digest[16];
  231.  
  232.     mdfour ((unsigned char *) digest, (unsigned char *) buffer, length);
  233.  
  234.     /*
  235.      * This is intentional.  digest can't be 4 unsigned integers because of
  236.      * possible alignment issues.
  237.      */
  238.     return ((unsigned *)digest)[0] ^
  239.                 ((unsigned *)digest)[1] ^
  240.                 ((unsigned *)digest)[2] ^
  241.                 ((unsigned *)digest)[3];
  242. }
  243.  
  244.